package textEngine.similarityFinderTest;


public class HistogramDistance {
	public static final String euclidean="Euclidean";
	public static final String manhattan="Manhattan";
	public static final String normalizedManhattan="Normalized-Manhattan";
	
	public static double getDistance(String s1, String s2,String distanceType){
		/**
		 * ATTENZIONE: NON SONO STATI CONSIDERATE LE PAROLE ACCENTATE (NON DANNO CONTRIBUTO!!)
		 * NON E' STATO NORMALIZZATO!!!
		 */
		//TODO: Da considerare gli ACCENTI!!!!
		
		int[] s1Hist= computeHistogram(s1);
		int[] s2Hist= computeHistogram(s2);
		
		double dist=0.0;
		
		if (distanceType.equals(euclidean)) dist = euclideanDistance(s1Hist, s2Hist);
		if (distanceType.equals(manhattan)) dist = manhattanDistance(s1Hist, s2Hist);
		if (distanceType.equals(normalizedManhattan)){
			s1Hist= computeWeighetdHistogram(s1);
			s2Hist= computeWeighetdHistogram(s2);
			dist = manhattanDistanceNormalized(s1Hist, s2Hist);
		}
		return dist;
	}
	
	public static int countLecter(int[] histogram){
		int count=0;
		for(int i=0; i<histogram.length; i++){
			count+=histogram[i];
		}
		return count;
	}
	
	

	private static double manhattanDistance(int[] s1Hist,int[] s2Hist){
		if(s1Hist.length!=s2Hist.length) return -1;
		double dist=0.0;
		for(int i=0; i<s1Hist.length;i++){
			dist+=Math.abs(s1Hist[i]-s2Hist[i]);
		}
		return dist;
	}
	private static double manhattanDistanceNormalized(int[] s1Hist,int[] s2Hist){
		//Normalizzo divendo per la somma delle lettere presenti nelle due stringhe a confronto 
		// considerando sempre che la prima lettera di ogni parola ha un peso diverso rispetto
		//alle altre.
		if(s1Hist.length!=s2Hist.length) return -1;
		double dist=0.0;
		for(int i=0; i<s1Hist.length;i++){
			dist+=Math.abs(s1Hist[i]-s2Hist[i]);
		}
		return dist;
	}
	
	public static double euclideanDistance(int[] s1HistP, int[] s2HistP) {
		
		//normalizzo gli Histograms:
		int totalSum1=0;
		int totalSum2=0;
		if(s1HistP.length!=s2HistP.length) return -1;
		
		for(int i=0;i<s1HistP.length;i++){
			totalSum1+=s1HistP[i];
			totalSum2+=s2HistP[i];
		}
		double[] s1Hist= new double[s1HistP.length];
		double[] s2Hist= new double[s2HistP.length];
		
		for(int i=0;i<s1HistP.length;i++){
			s1Hist[i]=((double)s1HistP[i])/((double)totalSum1);
			s2Hist[i]=((double)s2HistP[i])/((double)totalSum2);
		}
		
	
		double Sum = 0.0;
		
		
		for(int i=0; i<s1Hist.length;i++){
			
           Sum = Sum + Math.pow((s1Hist[i]-s2Hist[i]),2.0);
        }
        return Math.sqrt(Sum);
		
		
	}
	
	public static int histogramIntersection(int[] hist1, int[] hist2){
		
		int intersezione=0;
		for(int i=0;i<hist1.length&& i<hist2.length;++i){
			intersezione+=hist1[i]>=hist2[i]?hist2[i]:hist1[i];
		}
		return intersezione;
		
	}

	public static int[] computeHistogram(String s){
		
		//Non si distingua upper da lower case
		s= s.toLowerCase();
		int[] sHistogram= new int[26];
		
		//initializze
		for(int i=0; i<26; i++){
			sHistogram[i]=0;	
		}
		
		for(int i=0; i<s.length();i++){
			if(s.charAt(i)-97<26 && s.charAt(i)-97>=0){
				sHistogram[s.charAt(i)-97]++;
			}
		}
		return sHistogram;
		
	}
	private static int[] computeWeighetdHistogram(String s) {
		
		//Effettua una pesatura del primo carattere 
		//delle parole (es. Anna Lucci --> A ed L vengono moltiplicate per un fattore)
		int firstCharacterWeight=3;
		
		
		//Non si distingua upper da lower case
		s= s.toLowerCase();
		int[] sHistogram= new int[26];
		
		//initializze
		for(int i=0; i<26; i++){
			sHistogram[i]=0;	
		}
		boolean firstCharacther=true;
		for(int i=0; i<s.length();i++){
			if(s.charAt(i)-97<26 && s.charAt(i)-97>=0){
				if (firstCharacther){ 
					sHistogram[s.charAt(i)-97]+=firstCharacterWeight;
					firstCharacther=false;
				}
				else{
					sHistogram[s.charAt(i)-97]++;
				}
				
			}
			else if(Character.isWhitespace(s.charAt(i))){
				firstCharacther=true;
			}
		}
		return null;
	}

}
